package com.apps.sworld.dao;

import com.apps.sexctption.DataException;
import com.apps.sexctption.NullException;
import com.apps.shelper.ClassHelper;
import com.apps.sutils.StringUtils;
import com.apps.sworld.enums.TimeUnit;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.apps.shelper.AnnotationHelper;
import com.apps.saspect.ValidMethod;
import com.apps.sannotation.constraints.NoNull;
import com.apps.sannotation.constraints.NumMin;
import com.apps.sannotation.identity.CatId;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 所有分类对象的主类,万物皆被神管理且有分类,该类实现一些按分类进行操作的方法
 */
public interface sCat<T> extends sGod<T> {

    /**
     * 获取本分类ID的名称
     * @return
     */
    default String getCatIdName()
    {
        return AnnotationHelper.getAnnotationFieldName(CatId.class,currentModelClass());
    }
    @ValidMethod
    default int countByCatId(@NoNull Integer cat_id)
    {
        QueryWrapper<T> wrapper=new QueryWrapper<>();
        wrapper.eq(getCatIdName(),cat_id);
        return count(wrapper);
    }

    /**
     * 按分类id删除记录
     * @param cat_id
     */
    @ValidMethod
    default void deleteByCatId(@NoNull Integer cat_id)
    {
        QueryWrapper<T> wrapper=new QueryWrapper<>();
        wrapper.eq(getCatIdName(),cat_id);
        delete(wrapper);
    }
    /**
     * 按分类进行查询
     * @param cat_id
     * @return
     */
    @ValidMethod
    default T getOneByCatId(@NoNull Integer cat_id)
    {
        return getOneByFieldValue(getCatIdName(),cat_id);
    }

    /**
     * 获取不到就创建
     * @param cat_id
     * @param t
     * @return
     */
    @ValidMethod
    default T getOneByCatId(@NoNull Integer cat_id,@NoNull T t)
    {
        T result=getOneByCatId(cat_id);
        if(null == result)
        {
            String filedName=AnnotationHelper.getAnnotationFieldName(CatId.class,t.getClass());
            if(StringUtils.isEmpty(filedName))
                throw new NullException("分类id不存在或没添加注解进行标识");
            Object filedValue=ClassHelper.getFiledValue(t,filedName);
            if(null== filedValue) {
                ClassHelper.setFiledValue(filedName, t, cat_id);
                filedValue=cat_id;
            }
            if(!filedValue.equals(cat_id))
                throw new DataException("模型的分类id值必须等于传入的分类id");
            return saveToDB(t);
        }
        return result;
    }
    /**
     * 按cai_id校验对象结果集合是否为空
     * @param cat_id
     * @return
     */
    @ValidMethod
    default boolean isEmptyByCatId(@NoNull Integer cat_id)
    {
        QueryWrapper<T> wrapper=new QueryWrapper<>();
        wrapper.eq(getCatIdName(),cat_id);
        return isEmpty(wrapper);
    }

    @ValidMethod
    default boolean isEmptyByCatId(@NoNull Integer cat_id,@NoNull QueryWrapper<T> wrapper)
    {
        wrapper.eq(getCatIdName(),cat_id);
        return isEmpty(wrapper);
    }

    /**
     *
     * @param cat_id
     * @param pageNo
     * @param pageSize
     * @return
     */
    @ValidMethod
    default IPage<T> pageQueryByCatId(@NoNull Integer cat_id, @NumMin(min = 0) int pageNo, @NumMin(min = 0) int pageSize)
    {
        QueryWrapper<T> wrapper=new QueryWrapper<>();
        wrapper.eq(getCatIdName(),cat_id);
        return pageQuery(wrapper,pageNo,pageSize);
    }

    @ValidMethod
    default IPage<T> pageQueryByCatId(@NoNull Integer cat_id, @NumMin(min = 0) int pageNo, @NumMin(min = 0) int pageSize,@NoNull QueryWrapper<T> wrapper)
    {
        wrapper.eq(getCatIdName(),cat_id);
        return pageQuery(wrapper,pageNo,pageSize);
    }
    /**
     * 按分类id查询全部
     * @param cat_id
     * @return
     */
    @ValidMethod
    default List<T> queryByCatId(@NoNull Integer cat_id)
    {
        QueryWrapper<T> wrapper=new QueryWrapper<>();
        wrapper.eq(getCatIdName(),cat_id);
        return query(wrapper);
    }

    @ValidMethod
    default List<T> queryByCatId(@NoNull Integer cat_id,@NoNull QueryWrapper<T> wrapper)
    {
        wrapper.eq(getCatIdName(),cat_id);
        return query(wrapper);
    }
    /**
     * 按创建时间进行按年月日小时查询,传入的是字符串格式:2021090306 这样的格式
     * @param member_id
     * @param date
     * @param timeUnit
     * @return
     */
    @ValidMethod
    default List<T> queryGmtCreateByCatId(@NoNull Integer member_id,@NoNull String date, @NoNull TimeUnit timeUnit)
    {
        QueryWrapper<T> wrapper=new QueryWrapper<>();
        wrapper.eq(getCatIdName(),member_id);
        return queryByGmtCreate(wrapper,date,timeUnit);
    }
    /**
     * 按创建时间进行按年月日小时分页查询,传入的是字符串格式:2021090306 这样的格式
     * @param member_id
     * @param date 传入的是字符串格式:2021090306
     * @param timeUnit
     * @return
     */
    @ValidMethod
    default IPage<T> pageQueryGmtCreateByCatId(@NoNull Integer member_id,@NoNull String date, @NoNull TimeUnit timeUnit,int pageNo, int pageSize)
    {
        QueryWrapper<T> wrapper=new QueryWrapper<>();
        wrapper.eq(getCatIdName(),member_id);
        return pageQueryByGmtCreate(wrapper,date,timeUnit,pageNo,pageSize);
    }
    /**
     * 按时间区段分页查询
     * @param cat_id
     * @param start
     * @param end
     * @param pageNo
     * @param pageSize
     * @return
     */
    @ValidMethod
    default IPage<T> pageQueryTimeIntervalByCatId(@NoNull Integer cat_id, @NoNull LocalDateTime start, @NoNull LocalDateTime end, int pageNo, int pageSize)
    {
        QueryWrapper<T> wrapper=new QueryWrapper<>();
        wrapper.eq(getCatIdName(),cat_id);
        return pageQueryTimeInterval(wrapper,start,end,pageNo,pageSize);
    }

    /**
     * 按时间区间查询
     * @param cat_id
     * @param start
     * @param end
     * @return
     */
    @ValidMethod
    default List<T> queryTimeIntervalByCatId(@NoNull Integer cat_id, @NoNull LocalDateTime start, @NoNull LocalDateTime end)
    {
        QueryWrapper<T> wrapper=new QueryWrapper<>();
        wrapper.eq(getCatIdName(),cat_id);
        return queryTimeInterval(wrapper,start,end);
    }

    /**
     * 按分类id更新某个自动的值
     * @param cat_id
     * @param fieldname
     * @param value
     * @return
     */
    @ValidMethod
    default T updateOneFieldByCatId(@NoNull Integer cat_id,@NoNull String fieldname,@NoNull Object value)
    {
        T t=getOneByCatId(cat_id);
        if(null == t)
            throw new NullException("cat_id为"+cat_id+"的记录不存在");
        ClassHelper.setFiledValue(fieldname,t,value);
        return updateById(t);
    }

}
